package com.bridgeintelligent.tag.webserver.dim.mgmt.service.dimfree;

import com.bridgeintelligent.tag.constants.DimCofig;
import com.bridgeintelligent.tag.constants.ExceptionCodes;
import com.bridgeintelligent.tag.constants.PublicConstant;
import com.bridgeintelligent.tag.constants.TagConstants;
import com.bridgeintelligent.tag.mapper.*;
import com.bridgeintelligent.tag.remotefile.RemoteFileHandler;
import com.bridgeintelligent.tag.user.mgmt.pojo.User;
import com.bridgeintelligent.tag.utils.DateHelper;
import com.bridgeintelligent.tag.utils.FieldHandler;
import com.bridgeintelligent.tag.utils.SecurityHelper;
import com.bridgeintelligent.tag.webserver.dim.mgmt.api.*;
import com.bridgeintelligent.tag.webserver.dim.mgmt.service.catalog.model.DimFreeModel;
import com.bridgeintelligent.tag.webserver.dim.mgmt.service.catalog.model.DimListModel;
import com.bridgeintelligent.tag.webserver.dim.mgmt.service.dim.IDimService;
import com.bridgeintelligent.tag.webserver.dim.mgmt.service.dim.vo.DimVO;
import com.bridgeintelligent.tag.webserver.dim.mgmt.service.mq.SendMsgHandler;
import com.bridgeintelligent.tag.webserver.workflow.Instance;
import com.bridgeintelligent.tag.webserver.workflow.SubmitterService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Created by JackCheung on 2019/9/12 2:06 PM.
 */
@Service
@Slf4j
@AllArgsConstructor
public class DimFreeService implements IDimFreeService {

    private RemoteFileHandler remoteFileHandler;
    private DimFreeMapper dimFreeMapper;
    private DimItemMapper dimItemMapper;
    private DimMapper dimMapper;
    private DimFreeApprovalMapper dimFreeApprovalMapper;
    private IDimService dimService;
    private DimThemeMapper dimThemeMapper;
    private SubmitterService submitterService;
    private ObjectMapper objectMapper;
    private CatalogMapper catalogMapper;
    private SendMsgHandler sendMsgHandler;

    private static final String SUB_SIGN = "|";

    @Transactional(rollbackFor = Exception.class)
    @Override
    public DimRep add(DimFreeModel dimFreeModel, MultipartFile multipartFile) {
        DimData dbData = dimMapper.detail(dimFreeModel.getDimId());
        if (dbData != null) {
            return new DimRep(BaseCode.FAIL, "新增失败！标签ID重复！");
        }
        int result = dimMapper.findExits(dimFreeModel.getDimName());
        if (result > 0) {
            return new DimRep(BaseCode.FAIL, "新增失败！标签名称重复！");
        }
        // if (!checkFile(dimFreeModel.isEcifFlag(), multipartFile)) {
        if (!checkFile( multipartFile )) {
            return new DimRep<>(BaseCode.FAIL, " eicf/cust-no号错误上传失败，请重新上传。");
        }
       /* if (dimFreeModel.getCustAmount() > 1000000) {
            return new DimRep(BaseCode.FAIL, "新增失败！标签人数不能大于100万！");
        }*/
        List<DimItem> itemList = new ArrayList<>();
        try {
            itemList = objectMapper.readValue(dimFreeModel.getItemList(), new TypeReference<List<DimItem>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        String dimId = IdWorker.nextId();
        String filePath = upLoadFile(multipartFile, dimId);
        String time = DateHelper.currentDateTime();
        DimData dim = setDim(dimId, filePath, dimFreeModel, time);
        dim.setSortNum(getMaxOwerSortNum());//设置标签序号
        dim.setIsrecommended(false);
        dim.setWorking(dimFreeModel.isEcifFlag());
        dimFreeMapper.add(dim);
        dimItemMapper.delByDimId(dimId);
        setDimItem(dimId, time, itemList);
        return new DimRep<>(dim, BaseCode.SUCCESS);
    }

    // private boolean checkFile(boolean ecifFlag, MultipartFile multipartFile) {
    // NOTE ETL反馈: 北银的 one_id、cust_no、user_id 没有规则，故不做验证
    private boolean checkFile( MultipartFile multipartFile ) {
        File file = null;
        try {
            file = multipartFileToFile(multipartFile);
            try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file),
                                                                              StandardCharsets.UTF_8));) {
                String s;
                while ((s = br.readLine()) != null) {
                    String value = s.replaceAll("\uFEFF", "").trim();
                    String before = StringUtils.substringBefore(value, SUB_SIGN).trim();
                    String after = StringUtils.substringAfter(value, SUB_SIGN).trim();
                    if ( StringUtils.isBlank( before ) || StringUtils.isBlank( after) ) {
                        return false;
                    }
                    /*
                    if (ecifFlag) {
                        if (!(StringUtils.substringBefore(value, SUB_SIGN).length() == 10)) {
                            return false;
                        }
                    } else {
                        if (!(StringUtils.substringBefore(value, SUB_SIGN).length() == 19)) {
                            return false;
                        }
                    }
                    */
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != file) {
                file.delete();
            }
        }
        return true;
    }

    /**
     * 查询定制标签当前最大标签序号
     *
     * @return
     */
    private int getMaxOwerSortNum() {
        int maxSort = 100001;
        Integer sortNum = dimFreeMapper.findMaxOwerSortNum(DimCofig.FREE_DIM);
        if (null != sortNum && sortNum > 0) {
            maxSort = sortNum + 1;
        }
        return maxSort;
    }

    @Override
    public DimRep list(DimListModel dimListModel) {
        User user = SecurityHelper.currentUser();
        String userId = user.getUserId();
        Page page = PageHelper.startPage(dimListModel.getPageNumber(), dimListModel.getPageSize());

        List<DimData> list = new ArrayList<>();
        if (FieldHandler.isUnionAdmin(user.getRoleId())){
            //如果是超管
            list = dimFreeMapper.findUnionAdminList(userId,
                    dimListModel.getTheme(),
                    dimListModel.getDimName(),
                    dimListModel.getDepartment(),
                    dimListModel.getState(),
                    dimListModel.getCreateTimeStart(),
                    dimListModel.getCreateTimeEnd(),
                    dimListModel.getUptTimeStart(),
                    dimListModel.getUptTimeEnd(),
                    dimListModel.getApproveState());
        }else{
            list = dimFreeMapper.findList(userId,
                    dimListModel.getTheme(),
                    dimListModel.getDimName(),
                    dimListModel.getDepartment(),
                    dimListModel.getState(),
                    dimListModel.getCreateTimeStart(),
                    dimListModel.getCreateTimeEnd(),
                    dimListModel.getUptTimeStart(),
                    dimListModel.getUptTimeEnd(),
                    dimListModel.getApproveState());
        }

        boolean flag = false;
        for (DimData dimData:list) {
            if ("02".equals(dimData.getStatus())){
                flag = true;
                break;
            }
        }

        DimPage<DimData> dimDimPage = new DimPage<>();
        dimDimPage.setContent(list);
        dimDimPage.setTotalPages(page.getPages());
        dimDimPage.setTotalElements(page.getTotal());
        dimDimPage.setSize(page.getPageSize());
        dimDimPage.setRequestPager(dimListModel.getPageNumber());
        dimDimPage.setReflush(flag);
        return new DimRep<>(dimDimPage, BaseCode.SUCCESS);
    }

    @Override
    public DimRep detail(String dimId) {
        DimData dim = dimMapper.detail(dimId);
        List<DimItem> dimItems = dimItemMapper.list(dimId);
        if (dim == null) {
            dim = dimMapper.detailHistory(dimId);
            dimItems = dimItemMapper.listHistory(dimId);
        }
        DimVO dimVO = new DimVO(dim, dimItems);
        return new DimRep<>(dimVO, BaseCode.SUCCESS);
    }

    @Override
    public DimRep del(String dimId) {
        //Instance submit = submitterService.submit(new SubmitterService.SubmitParam().setResourceId(dimId)
        //.setWorkflowId(TagConstants.Workflow.ID_10003));
        //修改审批状态
        //updateApprovaleState(dimId, Integer.toString(submit.getCurrentStatus()));
        //删除自定义标签
        dimService.del(dimId);
        return new DimRep(BaseCode.SUCCESS);
    }

    @Override
    public DimRep delList(DimListModel dimListModel) {
        User user = SecurityHelper.currentUser();
        String userId = user.getUserId();
        List<DimDataDel> list = dimFreeMapper.findDelList(userId,
                                                          dimListModel.getTheme(),
                                                          dimListModel.getDimName(),
                                                          dimListModel.getDepartment(),
                                                          dimListModel.getState(),
                                                          dimListModel.getCreateTimeStart(),
                                                          dimListModel.getCreateTimeEnd(),
                                                          dimListModel.getUptTimeStart(),
                                                          dimListModel.getUptTimeEnd());
        Page page = PageHelper.startPage(dimListModel.getPageNumber(), dimListModel.getPageSize());
        DimPage<DimDataDel> dimDimPage = new DimPage<>();
        dimDimPage.setContent(list);
        dimDimPage.setTotalPages(page.getPages());
        dimDimPage.setTotalElements(page.getTotal());
        dimDimPage.setSize(page.getPageSize());
        dimDimPage.setRequestPager(dimListModel.getPageNumber());
        return new DimRep<>(dimDimPage, BaseCode.SUCCESS);
    }

    @Override
    public DimRep clear(String dimId) {
        checkDimDataRunning(dimId);
        Instance submit = submitterService.submit(new SubmitterService.SubmitParam().setResourceId(dimId)
                                                                                    .setWorkflowId(TagConstants.Workflow.ID_10004));
        //修改审批状态
        updateApprovaleState(dimId, Integer.toString(submit.getCurrentStatus()));
        return new DimRep(BaseCode.SUCCESS);
    }

    /**
     * 修改自定义标签的审核状态
     *
     * @param dimId
     * @param approvalState
     */
    @Override
    public void updateApprovaleState(String dimId, String approvalState) {
        if (approvalState != null && !"".equals(approvalState)) {
            dimFreeMapper.updateApprovaleState(dimId, approvalState);
        }
    }

    /**
     * 修改自定义标签的审核状态
     *
     * @param dimId
     * @param approvalState
     */
    @Override
    public void updateApproveState(String dimId, String approvalState, String approveDate) {
        if (approvalState != null && !"".equals(approvalState)) {
            dimFreeMapper.updateApproveState(dimId, approvalState, approveDate);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public DimRep updateBaseInfo(DimFreeModel dimFreeModel) {
        //????  这个方法代码是什么意思
        /*if (null != dimFreeModel.getCustAmount() && dimFreeModel.getCustAmount() > 1000000) {
            return new DimRep(BaseCode.FAIL, "修改失败！标签人数不能大于100万！");
        }*/
        DimData dim = dimMapper.detail(dimFreeModel.getDimId());
        if (!dimFreeModel.getDimName().equals(dim.getDimName())) {
            int result = dimMapper.findExits(dimFreeModel.getDimName());
            if (result > 0) {
                return new DimRep(BaseCode.FAIL, "更新失败！标签名称重复！");
            }
        }
        DimData dimData = dimMapper.detail(dimFreeModel.getDimId());
        String time = DateHelper.currentDateTime();
        DimData updateDim = setDim(dimData.getDimId(), dimData.getCustList(), dimFreeModel, time);
        updateDim.setSortNum(dimData.getSortNum());
        updateDim.setApproveState(dimData.getApproveState());
        dimMapper.update(updateDim);
        List<DimItem> itemList = new ArrayList<>();
        try {
            itemList = objectMapper.readValue(dimFreeModel.getItemList(), new TypeReference<List<DimItem>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        dimItemMapper.delByDimId(updateDim.getDimId());
        setDimItem(updateDim.getDimId(), time, itemList);
        /*DimDataApproval dimDataApproval = new DimDataApproval();
        try {
            dimService.fatherToChild(dimData, dimDataApproval);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        dimDataApproval.setDimId(dimFreeModel.getDimId())
                       .setDimName(dimFreeModel.getDimName())
                       .setDefinition(dimFreeModel.getDefinition())
                       .setScenarios(dimFreeModel.getScenarios())
                       .setCaliber(dimFreeModel.getCaliber())
                       .setCustAmount(dimFreeModel.getCustAmount())
                       .setValidTime(dimFreeModel.getValidTime());
        dimDataApproval.setApprovalId(IdWorker.nextId());
        dimDataApproval.setApproveState("2");
        dimDataApproval.setApprovalDate(DateHelper.currentDateTime());
        dimFreeApprovalMapper.add(dimDataApproval);
        //发起审批申请
        //发起审批申请
        Instance submit = submitterService.submit(new SubmitterService.SubmitParam().setResourceId(dimData.getDimId())
                                                                                    .setWorkflowId(TagConstants.Workflow.ID_10002));
        //修改审批状态
        updateApprovaleState(dimData.getDimId(), Integer.toString(submit.getCurrentStatus()));
        */
        return new DimRep<>(dimData, BaseCode.SUCCESS);
    }

    @Override
    public DimRep addCusts(String dimId, MultipartFile multipartFile, String fileDescription) {
        checkDimDataRunning(dimId);
        //发起审批申请
        Instance submit = submitterService.submit(new SubmitterService.SubmitParam().setResourceId(dimId)
                                                                                    .setWorkflowId(TagConstants.Workflow.ID_10005));
        //修改审批状态
        updateApprovaleState(dimId, Integer.toString(submit.getCurrentStatus()));
//        String filePath = iDimFreeFileUtils.saveAddFile(multipartFile, dimId);
//        dimMapper.updatePartCustList(filePath, dimId, fileDescription);
        return new DimRep(BaseCode.SUCCESS);
    }

    @Override
    public DimRep delCusts(String dimId, MultipartFile multipartFile, String fileDescription) {
        checkDimDataRunning(dimId);
        dimService.del(dimId);
        //发起审批申请
        //Instance submit = submitterService.submit(new SubmitterService.SubmitParam().setResourceId(dimId)
        // .setWorkflowId(TagConstants.Workflow.ID_10006));
        //修改审批状态
        // updateApprovaleState(dimId, Integer.toString(submit.getCurrentStatus()));
//        upLoadFile(multipartFile, dimId + "del");
//        String filePath = iDimFreeFileUtils.saveDelFile(multipartFile, dimId);
//        dimMapper.updatePartCustList(filePath, dimId, fileDescription);
        return new DimRep(BaseCode.SUCCESS);
    }

    @Override
    public void downLoad(String id, HttpServletResponse response, HttpServletRequest request) {
        DimData dimData = dimMapper.detail(id);
        if (dimData != null) {
            ByteArrayInputStream bis = null;
            OutputStream os = null;
            byte[] data = null;
            try {
                response.setContentType("text/plain;charset=UTF-8");
                String fileName = dimData.getDimName() + "_";
                String userAgent = request.getHeader("user-agent").toLowerCase();
                boolean flag = request.getHeader("User-Agent").indexOf("like Gecko") > 0;
                if (request.getHeader("User-Agent").toLowerCase().indexOf("msie") > 0 || flag) {
                    fileName = URLEncoder.encode(fileName, "UTF-8");//IE浏览器
                } else {
                    if (userAgent.contains("msie") || userAgent.contains("like gecko")) {
                        // win10 ie edge 浏览器 和其他系统的ie
                        fileName = URLEncoder.encode(fileName, "UTF-8");
                    } else {
                        // fe
                        fileName = new String(fileName.getBytes("utf-8"), "iso-8859-1");
                    }
                }
                response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".txt");
                data = InputStream2ByteArray(dimData.getCustList());
                bis = new ByteArrayInputStream(data);
                int i = bis.available();
                byte[] bytes = new byte[i];
                bis.read(bytes);
                os = response.getOutputStream();
                os.write(bytes);
                os.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    @Override
    public DimRep addById(DimFreeModel dimFreeModel) {
        DimData dbData = dimMapper.detail(dimFreeModel.getDimId());
        if (dbData != null) {
            return new DimRep(BaseCode.FAIL, "新增失败！标签ID重复！");
        }
        int result = dimMapper.findExits(dimFreeModel.getDimName());
        if (result > 0) {
            return new DimRep(BaseCode.FAIL, "新增失败！标签名称重复！");
        }
        /* if (dimFreeModel.getCustAmount() > 1000000) {
            return new DimRep(BaseCode.FAIL, "新增失败！标签人数不能大于100万！");
        }*/
        List<DimItem> itemList = new ArrayList<>();
        try {
            itemList = objectMapper.readValue(dimFreeModel.getItemList(), new TypeReference<List<DimItem>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        String dimId = dimFreeModel.getDimId();
        String time = DateHelper.currentDateTime();
        DimData dim = setDim(dimId, dimFreeModel.getFilePath(), dimFreeModel, time);
        dim.setSortNum(getMaxOwerSortNum());//设置标签序号
        dim.setIsrecommended(false);
        dim.setWorking(dimFreeModel.isEcifFlag());
        dim.setDataState("0");
        dim.setFileCode(dimFreeModel.getFileCode());
        dimFreeMapper.add(dim);
        dimItemMapper.delByDimId(dimId);
        setDimItem(dimId, time, itemList);
        //新增数据
        sendMsgHandler.sendMsg(dimId, 0);
        dimMapper.updateDimDataRunning(dimId, true,"0");
        return new DimRep<>(dim, BaseCode.SUCCESS);
    }

    @Override
    public DimRep up(String id, boolean ecifFlag, MultipartFile multipartFile) {
        String tempPath = remoteFileHandler.writeLocal(multipartFile);
        long lines = 0;
        try {
            lines = Files.lines(Paths.get(new File(tempPath).getPath())).count();
        } catch (IOException e) {
            log.error("----lines出现异常：{}",id);
            return new DimRep<>(BaseCode.FAIL, "校验文件失败");
        }
//        if (lines > 1000000) {
//            return new DimRep<>(BaseCode.FAIL, "不能超过100万数据");
//        }
        check(tempPath, tempPath + ".err", tempPath + ".ok");
        long oklines = 0;
        try {
            oklines = Files.lines(Paths.get(new File(tempPath + ".ok").getPath())).count();
        } catch (IOException e) {
            log.error("----oklines出现异常：{}",id);
            return new DimRep<>(BaseCode.FAIL, "校验文件失败");
        }
        String filePath = remoteFileHandler.uploadWhiteList(tempPath, id);
        remoteFileHandler.uploadByPath(tempPath + ".err", new File(filePath).getParent(), id + ".err");
        remoteFileHandler.uploadByPath(tempPath + ".ok", new File(filePath).getParent(), id + ".ok");
        if (oklines <= 0) {
            log.error("oklines小于0异常");
            return new DimRep<>(BaseCode.FAIL, "校验文件失败");
        }
        if (oklines < lines) {
            return new DimRep<>(filePath, 1, "部分成功！",oklines+"");
        }
        return new DimRep<>(filePath, BaseCode.SUCCESS,"全部成功",oklines+"");
    }

    @Override
    public void downLoadError(String id, HttpServletResponse response, HttpServletRequest request) {
        DimData dimData = dimMapper.detail(id);
        if (dimData != null) {
            ByteArrayInputStream bis = null;
            OutputStream os = null;
            byte[] data = null;
            try {
                response.setContentType("text/plain;charset=UTF-8");
                String fileName = dimData.getDimName()+"-异常客户号-"+ DateFormatUtils.format(new Date(), "yyyyMMdd");
                String userAgent = request.getHeader("user-agent").toLowerCase();
                boolean flag = request.getHeader("User-Agent").indexOf("like Gecko") > 0;
                if (request.getHeader("User-Agent").toLowerCase().indexOf("msie") > 0 || flag) {
                    fileName = URLEncoder.encode(fileName, "UTF-8");//IE浏览器
                } else {
                    if (userAgent.contains("msie") || userAgent.contains("like gecko")) {
                        // win10 ie edge 浏览器 和其他系统的ie
                        fileName = URLEncoder.encode(fileName, "UTF-8");
                    } else {
                        // fe
                        fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
                    }
                }
                response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".txt");
                data = InputStream2ByteArray(dimData.getCustList().replace(".txt", ".err"));
                bis = new ByteArrayInputStream(data);
                int i = bis.available();
                byte[] bytes = new byte[i];
                bis.read(bytes);
                os = response.getOutputStream();
                os.write(bytes);
                os.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    @SneakyThrows
    @Override
    public int doFileBakup(String type,String dimId,String startDate,String endDate) {
        int num = 0;
        switch (type){
            case "history":
                num = historyFilesBakup(null,null);
              break;
            case "error":
                num = errorFilesBakup();
               break;
            case "singal":
                num = singalBakup(dimId);
                break;
            case "period":
                num = historyFilesBakup(startDate,endDate);
                break;
            default:
                break;
        }
        return num;
    }
    @SneakyThrows
    private int historyFilesBakup(String startDate,String endDate){
        List<DimData> list = dimFreeMapper.findUnionAdminList("", "", "", "", "", startDate, endDate, "", "", "");
        List<String> result = new ArrayList<>();
        if(!list.isEmpty()){
            result = list.stream().filter(e->!e.getStatus().equals("01"))
                    .map(DimData::getCustList).collect(Collectors.toList());
        }
        log.info("=====>【历史定制标签文件】需备份的总量为：{}",result.size());
        for (String custList:result) {
            Thread.sleep(1000L);
            sendMsgHandler.sendFileBakUpMsg(custList);
        }
        return result.size();
    }
    @SneakyThrows
    private int errorFilesBakup(){
        List<String> result = dimFreeMapper.findErrorFiles(PublicConstant.ONE,PublicConstant.TWO);
        log.info("=====>【上传失败的定制标签文件】需备份的总量为：{}",result.size());
        for (String custList:result) {
            Thread.sleep(1000L);
            sendMsgHandler.sendFileBakUpMsg(custList);
        }
        return result.size();
    }
    @SneakyThrows
    private int singalBakup(String dimId){
        DimData dimData = dimMapper.detail(dimId);
        sendMsgHandler.sendFileBakUpMsg(dimData.getStatus().equals("01")?dimData.getCustList():null);
        return 1;
    }
    private final static String TITLE =
            "异常客户号的集中判定情况如下：异常客户号1.上传的客户号与选择的客户号类型位数不匹配。" + "异常客户号2.上传的客户号在行内数据库中未检索到。异常客户号3" +
                    ".只上传客户号未上传标签码值列、码值列为汉字。";

    public static boolean isContainChinese(String str) {
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }

    private void check( String path, String error, String ok ) {
        File file = new File(path);
        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file),
                                                                          StandardCharsets.UTF_8)); BufferedWriter errorWriter = new BufferedWriter(
                new OutputStreamWriter(new FileOutputStream(error))); BufferedWriter okWriter = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(ok)))) {
            errorWriter.write(TITLE);
            errorWriter.newLine();
            String s;
            while ((s = br.readLine()) != null) {
                String value = s.replaceAll("\uFEFF", "").trim() ;
                String before = StringUtils.substringBefore(value, SUB_SIGN).trim();
                String after = StringUtils.substringAfter(value, SUB_SIGN).trim();
                if ( StringUtils.isBlank( after ) || StringUtils.isBlank( before ) ) {
                    errorWriter.write(value);
                    errorWriter.newLine();
                    continue;
                }
                if (isContainChinese(after)) {
                    errorWriter.write(value);
                    errorWriter.newLine();
                    continue;
                }
                okWriter.write(value);
                okWriter.newLine();
            }
            okWriter.flush();
            errorWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private byte[] InputStream2ByteArray(String filePath) throws IOException {
        InputStream in = new FileInputStream(filePath);
        byte[] data = toByteArray(in);
        in.close();
        return data;
    }

    private byte[] toByteArray(InputStream in) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int n = 0;
        while ((n = in.read(buffer)) != -1) {
            out.write(buffer, 0, n);
        }
        return out.toByteArray();
    }

    private DimData setDim(String dimId, String filePath, DimFreeModel dimFreeModel, String time) {
        DimData dim = new DimData();
        User user = SecurityHelper.currentUser();
        String userId = user.getUserId();
        String department = user.getDepartment();
//        String userId = "123";
        dim.setCreaterId(userId);
        dim.setUptTime(time);
        dim.setCreateTime(time);
        dim.setDimId(dimId);
        dim.setBusinessType(dimFreeModel.getBusinessType());
        dim.setDimName(dimFreeModel.getDimName());
        dim.setTheme(dimFreeModel.getThemeId());
        dim.setDefinition(dimFreeModel.getDefinition());
        dim.setScenarios(dimFreeModel.getScenarios());
        dim.setValidTime(dimFreeModel.getValidTime());
        dim.setCaliber(dimFreeModel.getCaliber());
        dim.setCustList(filePath);
        dim.setUpdataCycle(dimFreeModel.getUpdataCycle());//更新频率
        dim.setClassify(dimFreeModel.getClassify());
        DimCatalog catalog = catalogMapper.findByCataName(TagConstants.PRIVATE_CATALOGID);
        dim.setCatalogId(catalog.getId());//目录
        dim.setCatalogName(TagConstants.PRIVATE_CATALOGID);
        dim.setBusinessLeader(dimFreeModel.getManager());
        dim.setBusinessDepartment(dimFreeModel.getDepartId());
        dim.setDimLargeType(DimCofig.FREE_DIM);
        dim.setDepartment(department);
        //dim.setApproveState(Integer.toString(Status.WAITTING.code()));
        dim.setApproveState("1");
        dim.setCustAmount(dimFreeModel.getCustAmount());
        dim.setFileCode(dimFreeModel.getFileCode());
        return dim;
    }

    private void setDimItem(String dimId, String time, List<DimItem> itemList) {
        itemList.forEach(e -> {
            DimItem dimItem = new DimItem();
            dimItem.setId(IdWorker.nextId());
            dimItem.setItemNo(e.getItemNo());
            dimItem.setDimId(dimId);
            dimItem.setUpdateDate(time);
            dimItem.setItemName(e.getItemName());
            dimItemMapper.add(IdWorker.nextId(), dimId, e.getItemNo(), e.getItemName(), e.getUpdateDate());
        });
    }

    private String upLoadFile(MultipartFile multipartFile, String dimId) {
        return remoteFileHandler.uploadWhiteList(remoteFileHandler.writeLocal(multipartFile), dimId);
    }

    private void checkDimDataRunning(String dimId) {
        DimData dimData = dimMapper.detail(dimId);
        if (dimData.isDataRunning()) {
            throw new DimException(ExceptionCodes.SECURITY_60001);
        }
    }

    private Map<String, String> getThemeMap() {
        return dimThemeMapper.list().stream().collect(Collectors.toMap(DimTheme::getId, DimTheme::getName));
    }
}
